# Log Page: https://build.tarsier-infra.com/package/live_build_log/openEuler:23.09:BaseOS:01/adobe-mappings-cmap/20230921/riscv64
# Raw Log File: https://build.tarsier-infra.com/public/build/openEuler:23.09:BaseOS:01/20230921/riscv64/adobe-mappings-cmap/_log
import requests
from requests.adapters import HTTPAdapter
import hashlib

import sys, re
import os

pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd + '../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'riscv_build_dataset.settings')

import django

django.setup()

from obs.models import obs_project, obs_package, obs_package_build_log, obs_job_history
from obs.mongo_log import OBSLog
import django.utils.timezone
from config import BASE_URL
from tqdm import tqdm

session = requests.Session()
session.mount('https://', HTTPAdapter(max_retries=5))


def get_log_file_from_url(project_name: str, repository_name: str, arch_name: str, package_name: str):
    url = f'{BASE_URL}/public/build/{project_name}/{repository_name}/{arch_name}/{package_name}/_log'
    resp = session.get(url, timeout=2)

    print('size', len(resp.text) / 1024 / 1024, 'M', end=' ')
    # with open('tmp.log', 'wb') as f:
    #     f.write(resp.content)
    # f.close()
    return resp.text


def log_status_test(log_text: str) -> str:
    lines = log_text.splitlines()
    last_lines = ''
    if len(lines) > 50:
        last_lines = '\n'.join(lines[-50:])
        # print(last_lines)
    if 'failed "build' in last_lines or 'Job seems to be stuck here, killed.' in last_lines:
        # print('failed')
        return 'failed'
    elif 'finished "build' in last_lines:
        # print('succeeded')
        return 'succeeded'
    else:
        # print('unknown')
        # print(lines)
        return 'unknown'


def save_log_to_db(project_name: str, package_name: str, log: str):
    project = obs_project.objects.get(project_name=project_name)
    package = obs_package.objects.get(project=project, package_name=package_name)
    o = OBSLog()
    if o.is_package_exist(package.id):
        # exist
        latest_log_md5 = o.get_latest_log_md5(package.id)
        log_md5 = hashlib.md5(log.encode('utf8')).hexdigest()
        if log_md5 == latest_log_md5:
            # same
            print("same as latest, skip saving")
            pass
        else:
            # not same
            _id = o.create(package.id, log, project.project_id)
            status = log_status_test(log)
            obs_package_build_log.objects.create(
                project=project,
                package=package,
                fetch_time=django.utils.timezone.now(),
                build_log_id=_id,
                status=status
            )
            try:
                pattern = r"srcmd5 '[0-9a-f]{32}'"
                find = re.search(pattern, log)
                if find:
                    srcmd5 = find.group().partition("'")[2][:-1]
                    # print(srcmd5)

                    job_hists = obs_job_history.objects.filter(srcmd5=srcmd5)
                    for j in job_hists:
                        j.mongo_log_id = _id
                        j.save()
                    # print(job_hist)
            except Exception as e:
                print(e, file=sys.stderr)

    else:
        _id = o.create(package.id, log, project.project_id)
        status = log_status_test(log)
        obs_package_build_log.objects.create(
            project=project,
            package=package,
            fetch_time=django.utils.timezone.now(),
            build_log_id=_id,
            status=status
        )
        try:
            pattern = r"srcmd5 '[0-9a-f]{32}'"
            find = re.search(pattern, log)
            if find:
                srcmd5 = find.group().partition("'")[2][:-1]
                # print(srcmd5)

                job_hists = obs_job_history.objects.filter(srcmd5=srcmd5)
                for j in job_hists:
                    j.mongo_log_id = _id
                    j.save()
                # print(job_hist)
        except Exception as e:
            print(e, file=sys.stderr)


if __name__ == '__main__':
    project_name = os.environ.get('OBS_PROJECT')
    repository_name = os.environ.get('OBS_REPO')
    arch_name = os.environ.get('OBS_ARCH')

    project = obs_project.objects.get(project_name=project_name)
    packages = obs_package.objects.filter(project=project)

    # package_name = 'adobe-mappings-cmap'
    # log = get_log_file_from_url(project_name, repository_name, architecture_name, package_name)
    # save_log_to_db(project_name, package_name, log)
    #
    # exit(0)

    o = OBSLog()

    for package in tqdm(packages):
        print(package.package_name, end=' ')
        package_name = package.package_name
        # For first fetch
        # if o.is_package_exist(package.id):
        #     print('exist, skipping for first fetch..')
        #     continue

        # For further updating
        try:
            log = get_log_file_from_url(project_name, repository_name, arch_name, package_name)
            save_log_to_db(project_name, package_name, log)
        except requests.exceptions.RequestException as e:
            print('\tRequest Exception..', file=sys.stderr)
            pass
        # time.sleep(1)
